<?php

namespace app\modules\backend\controllers;

use \app\models\cacheModel\NewsCategoryModel as NewsCategoryCacheModel;
use app\models\cacheModel\SettingModel;
use app\models\tableModel\NewsCategoryModel;
use app\service\tool\FileService;
use app\service\tool\UtilsService;
use \yii\console\Exception as consoleException;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;

/**
 * 文章分类管理
 * User: Administrator
 * Date: 2022/01/15
 * Time: 10:52:52
 */
class NewsCategoryController extends BaseController
{

    /**
     * {@inheritdoc}
     */
    public function behaviors()
    {
        return [
            'verbs' => [ // 请求方式
                'class' => VerbFilter::className(),
                'actions' => [
                    ### 页面
                    'index-page' => ['GET'],
                    'create-page' => ['GET'],
                    'update-page' => ['GET'],
                    ### 接口
                    'setting' => ['GET'],
                    'list' => ['GET'],
                    'detail' => ['GET'],
                    'create' => ['POST'],
                    'update' => ['POST'],
                    'disabled' => ['POST'],
                    'open' => ['POST'],
                    'show' => ['POST'],
                    'hide' => ['POST'],
                    'sort' => ['POST'],
                    'get-temp' => ['GET']
                ],
            ]
        ];
    }


    /**
     * 列表页面
     * @return mixed
     */
    public function actionIndexPage()
    {

        return $this->render('index', []);
    }

    /**
     * 创建页面
     * @return mixed
     */
    public function actionCreatePage()
    {

        return $this->render('create', []);
    }

    /**
     * 更新页面
     * @return mixed
     */
    public function actionUpdatePage()
    {

        // 编号
        $id = $this->get('id');

        // 验证 规格编号
        if (empty($id)) {

            return $this->showError('请传输编号，请确认信息编号是否正确。', 404);
        }

        // 实例化类 - 并根据编号查询
        $model = NewsCategoryModel::loadModel($id);
        // 编号非法返回
        if (empty($model)) {

            return $this->showError('数据条目不存在，请确认信息编号是否正确。', 404);
        }

        return $this->render('update', []);
    }


    /**
     * 获取设置
     *  ` PS: 获取某些设置(如：状态列表等)以供前端使用
     * @return mixed
     */
    public function actionSetting()
    {

        // 类型 - 一般为首页[index]、表单[form]
        $type = $this->get('type');

        // 模型
        $model = NewsCategoryModel::loadModel();
        return $this->jsonSuccess('成功', [
            'default_status' => !empty($type) && $type == 'index' ?
                '' : $model::getStatusOpen(), // 默认选中状态
            'default_is_show' => !empty($type) && $type == 'index' ?
                '' : $model::getIsShowShow(), // 默认 是否显示
            'default_url_type' => !empty($type) && $type == 'index' ?
                $model::getUrlTypeSite() : $model::getUrlTypeSite(), // 默认选中 链接类型
            'default_open_seo' => !empty($type) && $type == 'index' ?
                $model::getOpenSeoClose() : $model::getOpenSeoClose(), // 默认选中 是否开启SEO
            'status_list' => $model::getStatusList(), // 状态列表值
            'is_show_list' => $model::getIsShowList(), // 是否展示 列表值
            'open_seo_list' => $model::getOpenSeoList(), // 开启SEO列表值
            'url_type_list' => $model::getUrlTypeList(), // 链接类型列表值
            'min_sort' => $model::getMinSort(), // 最小排序值
            'max_sort' => $model::getMaxSort(), // 最大排序值
            'temp_pc_path' => (
                str_replace(\Yii::getAlias('@app'), '',  UtilsService::getFrontTempFolder(
                    'pc'
                ))
            ), // 模板路径
            'temp_mobile_path' => (
                str_replace(\Yii::getAlias('@app'), '',  UtilsService::getFrontTempFolder(
                    'mobile'
                ))
            ), // 模板路径
        ]);
    }

    /**
     * 列表
     * @return mixed
     */
    public function actionList()
    {

        // 查询内容
        $search = $this->get('search');
        // 显示当前第几页
        $page = $this->get('page', 1, 'int');
        // 每页显示多少条
        $pageSize = $this->getPageSize();
        // 排序字段
        $sort = $this->getSort();

        ### 普通设置
        $opt = [];
        // 是否加载[其是否存在子集]
        $opt['loadHasChild'] = $this->get('option.load_has_child', false, 'bool');
        // 加载子集
        $opt['loadChild'] = $this->get('option.load_child', false, 'bool');
        // 子集没有是否删除键值
        $opt['childNoDel'] = $this->get('option.child_no_del', false, 'bool');

        ### 其他有逻辑的设置
        $clientOpt = $this->get('option');
        // 加载子集
        if (!empty($clientOpt['load_child_ids'])) {
            $opt['loadChild'] = !is_array($clientOpt['load_child_ids']) ?
                explode(',', $clientOpt['load_child_ids']) : $clientOpt['load_child_ids'];
        }
        // 排除子集
        if (!empty($clientOpt['removeIds'])) {
            $opt['removeIds'] = !is_array($clientOpt['remove_ids']) ?
                explode(',', $clientOpt['remove_ids']) : $clientOpt['remove_ids'];
        }

        // 字段1
        $field = [
            'id',
            'name',
            'parent_id',
            'status',
            'is_show',
            'sort',
            'level',
            'description',
            'url_type',
            'url',
            'add_time',
            'update_time',
            'extra_article'
        ];

        // 父级别[model]
        $model = NewsCategoryModel::loadModel();

        // 分页数据
        $paginate = $model->loadWhere($search)->loadSort($sort)->getPaginate($page, $pageSize, $field, $opt);

        return $this->jsonSuccess('成功', [
            'total' => $paginate->getTotal(),
            'list' => $paginate->getList()
        ]);
    }

    /**
     * 详情
     * @param string $id 编号
     * @return mixed
     */
    public function actionDetail()
    {

        // 获取全部POST数据
        $id = $this->get('id');

        // 验证 规格编号
        if (empty($id)) {

            return $this->jsonFail('数据不存在', 404, [
                'hint' => '请传输编号'
            ]);
        }

        $model = NewsCategoryModel::loadModel($id);

        if ($model == null) {

            return $this->jsonFail('数据不存在', 404, [
                'hint' => '数据不存在，请核对'
            ]);
        }

        // 仅仅返回指定 字段
        $detail = $model->getAttributes([
            'id',
            'name',
            'parent_id',
            'status',
            'is_show',
            'sort',
            'description',
            'setting',
            'news_setting',
            'url_type',
            'url',
            'image',
            'pc_cate_temp',
            'pc_list_temp',
            'pc_detail_temp',
            'mob_cate_temp',
            'mob_list_temp',
            'mob_detail_temp',
            'extra_data',
            'extra_article',
            'add_time',
            'update_time',
        ]);

        // 详情 格式化
        if (!empty($detail['description'])) {
            $detail['description'] = htmlspecialchars_decode($detail['description']);
        }

        ### 模板页页 键塑造
        $fields = [
            'pc_cate_temp',
            'pc_list_temp',
            'pc_detail_temp',
            'mob_cate_temp',
            'mob_list_temp',
            'mob_detail_temp'
        ];
        foreach ($fields as $k => $v) {
            $stage = '';
            $detail[$v . '_key'] = [];
            foreach (explode('/', $detail[$v]) as $k2 => $v2) {
                if (empty($v2)) continue;
                $stage .= '/' . $v2;
                $detail[$v . '_key'][] = md5($stage);
            }
        }

        return $this->jsonSuccess('成功', $detail);
    }

    /**
     * 创建
     * @return mixed
     */
    public function actionCreate()
    {

        // 赋值所需数据
        $data = $this->post();

        // 实例化类
        $model = NewsCategoryCacheModel::loadModel();
        // 加载类数据
        $model->load($data, '');

        // 数据保存失败并返回错误信息
        if (!$model->save()) {

            $error = $model->getFirstErrors();
            return $this->jsonFail('添加失败, 请确认各项数据是否合法', 400, [
                'column_error' => UtilsService::getChineseErr($error)
            ]);
        }

        // 成功返回
        return $this->jsonSuccess('成功');
    }

    /**
     * 更新
     * @return mixed
     */
    public function actionUpdate()
    {

        // 编号
        $id = $this->post('id');

        // 实例化类 - 并根据编号查询
        $model = NewsCategoryCacheModel::loadModelDB(['id' => $id]);
        // 编号非法返回
        if (empty($model)) {

            return $this->jsonFail('数据不存在', 400, [
                'hint' => '数据未找到'
            ]);
        }

        // 赋值所需数据
        $data = $this->post();

        // 加载类数据
        $model->load($data, '');

        // 数据保存失败并返回错误信息
        if (!$model->save()) {

            $error = $model->getFirstErrors();
            return $this->jsonFail('修改失败, 请确认各项数据是否合法', 400, [
                'column_error' => UtilsService::getChineseErr($error)
            ]);
        }

        // 成功返回
        return $this->jsonSuccess('成功');
    }

    /**
     * 禁用条目
     * @param array $idList 数据条目|多条数组格式，如：[1,2,3]
     * @return mixed
     */
    public function actionDisabled()
    {

        // 编号列表获取
        $idList = $this->post('idList');
        // 不是数组塑造下 为了构成100%的数组
        if (!empty($idList) && !is_array($idList)) $idList = explode(',', $idList);
        // 看获取的编号列表是否合法
        if (empty($idList) || count($idList) <= 0) {

            return $this->jsonFail('请选择一个条目', 400, [
                'hint' => '未传输任何编号'
            ]);
        }

        // 检测多选条目
        $maxIdCount = $this->getMaxIdCount();
        if (count($idList) > intval($maxIdCount)) {
            return $this->jsonFail('每次最多选择操作' . $maxIdCount . '条数据', 400);
        }

        // 条件
        $condition = ['AND', ['IN', 'id', $idList]];
        // 修改的字段
        $field = ['status' => NewsCategoryModel::getStatusDisabled()];
        // 是否操作成功 - 错误一般记录到[log]日志
        if (!NewsCategoryCacheModel::updateField($condition, $field)) {

            // 将返回数据库级错误，暂不返回 会在日志中记录
            return $this->jsonFail('请求频繁请稍后尝试', 500, [
                'err_detail' => '出现致命错误。请查看日志',
                'err_code' => 500
            ]);
        }

        return $this->jsonSuccess('成功');
    }

    /**
     * 开启条目
     * @param array $idList 数据条目|多条数组格式，如：[1,2,3]
     * @return mixed
     */
    public function actionOpen()
    {

        // 编号列表获取
        $idList = $this->post('idList');
        // 不是数组塑造下 为了构成100%的数组
        if (!empty($idList) && !is_array($idList)) $idList = explode(',', $idList);
        // 看获取的编号列表是否合法
        if (empty($idList) || count($idList) <= 0) {

            return $this->jsonFail('请选择一个条目', 400, [
                'hint' => '未传输任何编号'
            ]);
        }

        // 检测多选条目
        $maxIdCount = $this->getMaxIdCount();
        if (count($idList) > intval($maxIdCount)) {
            return $this->jsonFail('每次最多选择操作' . $maxIdCount . '条数据', 400);
        }

        // 条件
        $condition = ['AND', ['IN', 'id', $idList]];
        // 修改的字段
        $field = ['status' => NewsCategoryModel::getStatusOpen()];
        // 是否操作成功 - 错误一般记录到[log]日志
        if (!NewsCategoryCacheModel::updateField($condition, $field)) {

            // 将返回数据库级错误，暂不返回 会在日志中记录
            return $this->jsonFail('请求频繁请稍后尝试', 500, [
                'err_detail' => '出现致命错误。请查看日志',
                'err_code' => 500
            ]);
        }

        return $this->jsonSuccess('成功');
    }

    /**
     * 隐藏条目
     * @param array $idList 数据条目|多条数组格式，如：[1,2,3]
     * @return mixed
     */
    public function actionHide()
    {

        // 编号列表获取
        $idList = $this->post('idList');
        // 不是数组塑造下 为了构成100%的数组
        if (!empty($idList) && !is_array($idList)) $idList = explode(',', $idList);
        // 看获取的编号列表是否合法
        if (empty($idList) || count($idList) <= 0) {

            return $this->jsonFail('请选择一个条目', 400, [
                'hint' => '未传输任何编号'
            ]);
        }

        // 检测多选条目
        $maxIdCount = $this->getMaxIdCount();
        if (count($idList) > intval($maxIdCount)) {
            return $this->jsonFail('每次最多选择操作' . $maxIdCount . '条数据', 400);
        }

        // 条件
        $condition = ['AND', ['IN', 'id', $idList]];
        // 修改的字段
        $field = ['is_show' => NewsCategoryModel::getIsShowHide()];
        // 是否操作成功 - 错误一般记录到[log]日志
        if (!NewsCategoryCacheModel::updateField($condition, $field)) {

            // 将返回数据库级错误，暂不返回 会在日志中记录
            return $this->jsonFail('请求频繁请稍后尝试', 500, [
                'err_detail' => '出现致命错误。请查看日志',
                'err_code' => 500
            ]);
        }

        return $this->jsonSuccess('成功');
    }

    /**
     * 展示条目
     * @param array $idList 数据条目|多条数组格式，如：[1,2,3]
     * @return mixed
     */
    public function actionShow()
    {

        // 编号列表获取
        $idList = $this->post('idList');
        // 不是数组塑造下 为了构成100%的数组
        if (!empty($idList) && !is_array($idList)) $idList = explode(',', $idList);
        // 看获取的编号列表是否合法
        if (empty($idList) || count($idList) <= 0) {

            return $this->jsonFail('请选择一个条目', 400, [
                'hint' => '未传输任何编号'
            ]);
        }

        // 检测多选条目
        $maxIdCount = $this->getMaxIdCount();
        if (count($idList) > intval($maxIdCount)) {
            return $this->jsonFail('每次最多选择操作' . $maxIdCount . '条数据', 400);
        }

        // 条件
        $condition = ['AND', ['IN', 'id', $idList]];
        // 修改的字段
        $field = ['is_show' => NewsCategoryModel::getIsShowShow()];
        // 是否操作成功 - 错误一般记录到[log]日志
        if (!NewsCategoryCacheModel::updateField($condition, $field)) {

            // 将返回数据库级错误，暂不返回 会在日志中记录
            return $this->jsonFail('请求频繁请稍后尝试', 500, [
                'err_detail' => '出现致命错误。请查看日志',
                'err_code' => 500
            ]);
        }

        return $this->jsonSuccess('成功');
    }

    /**
     * 排序
     * @param array $idList 数据条目|多条数组格式，如：[1,2,3]
     * @return mixed
     */
    public function actionSort()
    {

        // 编号列表获取
        $idList = $this->post('idList');
        // 不是数组塑造下 为了构成100%的数组
        if (!empty($idList) && !is_array($idList)) $idList = explode(',', $idList);
        // 看获取的编号列表是否合法
        if (empty($idList) || count($idList) <= 0) {

            return $this->jsonFail('编号不能为空', 400);
        }

        // 检测多选条目
        $maxIdCount = $this->getMaxIdCount();
        if (count($idList) > intval($maxIdCount)) {
            return $this->jsonFail('每次最多选择操作' . $maxIdCount . '条数据', 400);
        }

        // 排序值获取
        $sort = $this->post('sort', 0);
        // 看获取的[data]是否为空
        if (!isset($sort)) return $this->jsonFail('排序不能为空', 400);

        // 条件
        $condition = ['AND', ['IN', 'id', $idList]];
        // 修改的字段
        $field = ['sort' => $sort];
        if (!NewsCategoryCacheModel::updateField($condition, $field)) {

            // 将返回数据库级错误，暂不返回 会在日志中记录
            return $this->jsonFail('请求频繁请稍后尝试', 500, [
                'err_detail' => '出现致命错误。请查看日志',
                'err_code' => 500
            ]);
        }

        return $this->jsonSuccess('成功');
    }

    /**
     * 获取模板文件列表
     */
    public function actionGetTemp()
    {

        // 当前打开的文件夹
        $openPath = \Yii::$app->request->get('openPath');
        // 命名空间替换回路径
        $openPath = str_replace('app\\', '@app', $openPath);
        // 命名空间替换回路径
        $openPath = str_replace('@template/', '/template/', $openPath);
        // 命名空间替换回路径
        $openPath = str_replace('\\', '/', $openPath);

        // 转化下别名为路径
        $openPath = \Yii::getAlias('@app' . $openPath);

        $endData = FileService::getFileList($openPath, []);
        return $this->jsonSuccess('成功', $endData);
    }
}
